package org.iteam.bank.signed.action;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Result;
import org.apache.struts2.convention.annotation.Results;
import org.iteam.bank.mina.utils.ConfigLoader;
import org.iteam.bank.mina.utils.HexUtils;
import org.iteam.bank.mina.utils.IpUtils;
import org.iteam.bank.mina.utils.NumberUtils;
import org.iteam.bank.signed.model.*;
import org.iteam.bank.signed.service.*;
import org.iteam.commons.codec.AESCoder;
import org.iteam.commons.codec.HMACCoder;
import org.iteam.db.exception.DbException;
import org.iteam.mina.Constant;

import java.util.Arrays;

@SuppressWarnings("unchecked")
@Results({ @Result(type = "freemarker", name = "index", location = "/WEB-INF/content/platform/elect-pay.html") })
public class SubscribeAction extends BaseAction {
	private static final long serialVersionUID = 6893003861683165618L;

	private String subscribeParams;// 绑卡加密参数
	private String subscribeSign;// 绑卡加密签名
	private static final String SESSION_SUBSCRIBE_CARD_INFO = "SESSION_SUBSCRIBE_CARD_INFO";// 认购基础信息
	private String dealno;
	private String captcha;
	private String seqCode;
	private String password;

	@Action("/subscribe")
	public String subscribe() {
		init();
		logger.debug("接收认购请求:subscribeParams={}", subscribeParams);
		logger.debug("接收认购请求:subscribeSign={}", subscribeSign);
		try {
			// 验证签名
			byte[] content = HexUtils.decodeHexByte(subscribeParams);
			byte[] oldSign = HexUtils.decodeHexByte(subscribeSign);
			// bindCard.KEY_HMAC
			// bindCard.KEY_AES
			byte[] sign = HMACCoder.encryptHMAC(content, ConfigLoader.get("subscribe.KEY_HMAC"));
			if (Arrays.equals(sign, oldSign)) {
				// 签名验证成功，进入解密流程
				byte[] eContent = AESCoder.decrypt(content, ConfigLoader.get("subscribe.KEY_AES"));
				JSONObject params = JSON.parseObject(new String(eContent, Constant.UTF_8));
				logger.debug("接收认购请求:subscribeParams[解密后]={}", params.toJSONString());
				String p2p_user_id = params.getString("p2p_user_id");
				String p2p_project_id = params.getString("p2p_project_id");
				String dealno = params.getString("dealno");
				// params.getIntValue("accountType");
				// params.getString("notifyUrl");
				// params.getString("callBack");
				if (StringUtils.isBlank(p2p_user_id) || StringUtils.isBlank(p2p_project_id) || StringUtils.isBlank(dealno)) {
					return subscribeError(ConfigLoader.get("PC_URL"), "认购信息错误，请重试", "文创汇");
				}
				P2PUserInfo info = P2PUserService.getInstance().showById(p2p_user_id);
				map.put("info", info);
				if (info == null) {
					return subscribeError(ConfigLoader.get("PC_URL"), "认购信息验证错误，请重试", "文创汇");
				} else {
					// 2审核中 1为已认证，0为未认证，默认为0
					switch (info.getCardNoStatus().intValue()) {
					case 0:
						return subscribeWarn(ConfigLoader.get("PC_URL"), "您尚未绑卡，请先绑卡", "文创汇");
					case 2:
						return subscribeWarn(ConfigLoader.get("PC_URL"), "您的绑卡信息尚在处理中，请稍候重试", "文创汇");
					case 1:
						break;
					default:
						break;
					}
				}
				P2PPayAccount p2pPayAccount = P2PUserService.getInstance().showPayInfo(info.getUserName());
				// 验证绑卡信息
				if (p2pPayAccount == null || StringUtils.isBlank(p2pPayAccount.getEcard_no()) || StringUtils.isBlank(p2pPayAccount.getCard_no())) {
					return subscribeError(ConfigLoader.get("PC_URL"), "您的绑卡信息未找到", "文创汇");
				}
				// 验证支付密码状态
				if (StringUtils.isBlank(p2pPayAccount.getPay_password())) {
					return subscribeError(ConfigLoader.get("PC_URL"), "您的支付密码尚未设置", "文创汇");
				}

				// 查询项目信息
				P2PProject project = P2PProjectService.getInstance().show(p2p_project_id);
				if (project == null) {
					return subscribeError(ConfigLoader.get("PC_URL"), "认购信息错误，请重试", "文创汇");
				}
				if (project.getStatus().intValue() != 30) {
					return subscribeError(ConfigLoader.get("PC_URL"), "该项目暂时无法进行认购", "文创汇");
				}
				// 查询订单信息
				P2POrder order = P2POrderService.getInstance().show(dealno);
				if (order == null) {
					return subscribeError(ConfigLoader.get("PC_URL"), "认购信息错误，请重试", "文创汇");
				}
				// 1成功，0失败，-1 申请
				switch (order.getStatus()) {
				case 0:
					return subscribeWarn(ConfigLoader.get("PC_URL"), "该订单已经支付过了，请勿重复支付", "文创汇");
				case -1:
					break;
				case 1:
					return subscribeWarn(ConfigLoader.get("PC_URL"), "该订单已经支付过了，请勿重复支付", "文创汇");
				default:
					break;
				}
				// 查询用户余额
				AccountBalance balance = GSPService.getInstance().queryBalance(p2pPayAccount.getEcard_no(), p2pPayAccount.getName(),
						p2pPayAccount.getProtocol_no());
				map.put("p", project);
				map.put("order", order);
				map.put("pay", p2pPayAccount);
				map.put("balance", balance);
				map.put("availableBalance", NumberUtils.getNumberSString(balance.getAvailableBalance()));
				map.put("amount", NumberUtils.getNumberSString(order.getAmount()));
				session.put(SESSION_SUBSCRIBE_CARD_INFO.concat(dealno), params.toJSONString());
				map.put("isBalance", true);
				if (balance.getAvailableBalance().compareTo(order.getAmount()) == -1) {
					map.put("isBalance", false);
				}
			}
		} catch (DbException e) {
			logger.error(e.getMessage(), e);
			return subscribeError(ConfigLoader.get("PC_URL"), "认购信息验证错误，请重试", "文创汇");
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
			return subscribeError(ConfigLoader.get("PC_URL"), "认购信息验证错误，请重试", "文创汇");
		}
		return "index";
	}

	/**
	 * 发送绑定银行卡验证码
	 * 
	 * @return
	 */

	@Action("/subscribe/sendSms")
	public String sendBingdCaptcha() {
		try {
			JSONObject jsonObject = JSON.parseObject(session.get(SESSION_SUBSCRIBE_CARD_INFO.concat(dealno)).toString());
			String p2p_user_id = jsonObject.getString("p2p_user_id");
			P2PUserInfo info = P2PUserService.getInstance().showById(p2p_user_id);
			JSONObject json = SMSService.getInstance().sendSms(info.getMobile(), SMSService.TYPE_PAY_PASSWORD);
			if (SMSService.isSuccess(json)) {
				map.put("state", true);
				map.put("serialNo", SMSService.getID(json));
				map.put("info", "发送成功");
			} else {
				map.put("state", false);
				map.put("info", "验证码发送失败,请稍候重试");
			}
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
			map.put("state", false);
			map.put("info", "系统繁忙,请稍候重试");
		}
		return MAP;
	}

	@Action("/subscribe/pay")
	public String subscribe_pay() {
		try {
			boolean result = true;
			JSONObject jsonObject = JSON.parseObject(session.get(SESSION_SUBSCRIBE_CARD_INFO.concat(dealno)).toString());
			String p2p_user_id = jsonObject.getString("p2p_user_id");
//			String directPasswrd = jsonObject.getString("password");
			if (StringUtils.isBlank(dealno)) {
				result = false;
				map.put("state", false);
				map.put("info", "非法支付");
			}
			if (result && (StringUtils.isBlank(captcha) || StringUtils.isBlank(seqCode))) {
				result = false;
				map.put("state", false);
				map.put("info", "验证码不能为空");
			}
			if (result && StringUtils.isBlank(password)) {
				result = false;
				map.put("state", false);
				map.put("info", "支付密码不能为空");
			}
			P2POrder order = null;
			if (result) {
				order = P2POrderService.getInstance().show(dealno);
				if (order == null || !StringUtils.equals(p2p_user_id, order.getP2pUser_id())) {
					result = false;
					map.put("state", false);
					map.put("info", "非法支付");
				}
			}
			P2PUserInfo info = null;
			if (result) {
				info = P2PUserService.getInstance().showById(p2p_user_id);
				JSONObject json = SMSService.getInstance().validateSms(info.getMobile(), SMSService.TYPE_PAY_PASSWORD, seqCode, captcha);
				// 验证支付验证码
				if (!SMSService.isSuccess(json)) {
					result = false;
					map.put("state", false);
					map.put("info", "验证码输入错误");
				}
			}
			String p2p_project_id = jsonObject.getString("p2p_project_id");
			// 验证项目是否满标
			if (result) {
				P2PProject project = P2PProjectService.getInstance().show(p2p_project_id);
				if (project.getStatus().intValue() != 30) {
					result = false;
					map.put("state", false);
					map.put("info", "该项目暂时无法进行投标");
				}
				if (result) {
					// 判断项目是否可投
					// -1 小于 0 等于 1 大于
					if (project.getProjectAmount().subtract(project.getCastAmount()).compareTo(order.getAmount()) == -1) {
						result = false;
						map.put("state", false);
						map.put("info", "项目可投余额不足");
					}
				}
				if (result) {
					// 判断项目起投金额是否满足
					// 0 倍投 1 非倍投
					switch (project.getDoubleYes()) {
					case 0:// 0 倍投
						if (order.getAmount().doubleValue() % project.getTenderAccountMin().doubleValue() != 0) {
							map.put("state", false);
							map.put("info", "项目投资金额必须是".concat(NumberUtils.getNumberSString(project.getTenderAccountMin())).concat("元的整数倍"));
							result = false;
						}
						break;
					case 1:// 0 倍投
						if (order.getAmount().compareTo(project.getTenderAccountMin()) == -1) {
							map.put("state", false);
							map.put("info", "项目最小投资金额为".concat(NumberUtils.getNumberSString(project.getTenderAccountMin())).concat("元"));
							result = false;
						}
						break;
					default:
						break;
					}
				}
//				if (result) {
//					// 判断项目是否是定向标
//					if (project.getDirect().intValue() == 1) {
//						if (!project.getDirectPassword().equals(directPasswrd)) {
//							map.put("state", false);
//							map.put("info", "定向密码输入错误");
//							result = false;
//						}
//					}
//				}
				P2PPayAccount payAccount = null;
				// 验证余额
				if (result) {
					payAccount = P2PUserService.getInstance().showPayInfo(info.getUserName());
					if (payAccount == null) {
						map.put("state", false);
						map.put("info", "绑卡信息查询错误");
						result = false;
					}
				}
				AccountBalance accountBalance = null;
				if (result) {
					accountBalance = GSPService.getInstance().queryBalance(payAccount.getEcard_no(), payAccount.getName(), payAccount.getProtocol_no());
					if (accountBalance == null) {
						map.put("state", false);
						map.put("info", "账户余额查询失败");
						result = false;
					}
				}
				// 判断余额是否充足
				if (result) {
					// -1 小于 0 等于 1 大于
					if (!(order.getAmount().compareTo(accountBalance.getAvailableBalance()) != 1)) {
						map.put("state", false);
						map.put("info", "账户余额不足");
						result = false;
					}
				}
				// 判断支付密码是否正确
				if (result) {
					if (!StringUtils.equals(SubscribeService.encryptionPayPassword(password), payAccount.getPay_password())) {
						map.put("state", false);
						map.put("info", "支付密码输入错误");
						result = false;
					}
				}
				// 开始投标
				if (result) {
					StringBuffer errorMsg = new StringBuffer();
					result = SubscribeService.getInstance().orderPay(p2p_user_id, p2p_project_id, dealno, IpUtils.ip(request), payAccount, accountBalance,
							errorMsg);
					if (result) {
						map.put("state", true);
						map.put("info", "投标成功");
						map.put("callBack", jsonObject.getString("callBack"));
					} else {
						if (errorMsg.length() == 0) {
							errorMsg.append("投标失败");
						}
						map.put("state", false);
						map.put("info", errorMsg.toString());
					}
				}
			}
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
			map.put("state", false);
			map.put("info", "系统繁忙,请稍候重试");
		}
		return MAP;
	}

	public String getSubscribeParams() {
		return subscribeParams;
	}

	public void setSubscribeParams(String subscribeParams) {
		this.subscribeParams = subscribeParams;
	}

	public String getSubscribeSign() {
		return subscribeSign;
	}

	public void setSubscribeSign(String subscribeSign) {
		this.subscribeSign = subscribeSign;
	}

	public String getDealno() {
		return dealno;
	}

	public void setDealno(String dealno) {
		this.dealno = dealno;
	}

	public String getCaptcha() {
		return captcha;
	}

	public void setCaptcha(String captcha) {
		this.captcha = captcha;
	}

	public String getSeqCode() {
		return seqCode;
	}

	public void setSeqCode(String seqCode) {
		this.seqCode = seqCode;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

}
